home *** CD-ROM | disk | FTP | other *** search
- unit DCMemo;
-
- interface
-
- uses
- SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
- Forms, Dialogs, StdCtrls;
-
- type
- TDCMemo = class(TMemo)
- private
- FAutoScrollBar: Boolean;
- procedure SetAutoScrollBar(const Value: Boolean);
- function TextHeight(const Msg: String): Integer;
- protected
- procedure Change; override;
- procedure CheckScrollBar; virtual;
- published
- property AutoScrollBar: Boolean
- read FAutoScrollBar write SetAutoScrollBar default False;
- end;
-
- procedure Register;
-
- implementation
-
- procedure Register;
- begin
- RegisterComponents('Clinic', [TDCMemo]);
- end;
-
- { TDCMemo }
-
- function TDCMemo.TextHeight(const Msg: String): Integer;
- var
- DC: HDC;
- OldFont: HFont;
- Size: TSize;
- begin
- { Can't just ask a control for the font height, as Delphi }
- { caches the font and doesn't select it into the device }
- { context until some drawing is required. }
- { The memo may have a different font to its form and under }
- { those circumstances, you could get bad results. }
-
- { Access control's device context }
- DC := GetDC(Handle);
- try
- { Ensure font is selected into DC (saving old font) }
- OldFont := SelectObject(DC, Font.Handle);
- try
- { Find text height }
- {$ifdef Win32}
- Win32Check(GetTextExtentPoint32(DC, PChar(Msg), 1, Size));
- {$else}
- GetTextExtentPoint(DC, @(Msg[1]), 1, Size);
- {$endif}
- Result := Size.cy
- finally
- { Put old font back into memo }
- SelectObject(DC, OldFont)
- end;
- finally
- { Let the DC go }
- ReleaseDC(Handle, DC)
- end;
- end;
-
- procedure TDCMemo.Change;
- begin
- inherited Change;
- CheckScrollBar
- end;
-
- procedure TDCMemo.SetAutoScrollBar(const Value: Boolean);
- begin
- if FAutoScrollBar <> Value then
- begin
- FAutoScrollBar := Value;
- CheckScrollBar;
- end
- end;
-
- procedure TDCMemo.CheckScrollBar;
- var
- MemoNumLines: Integer;
- OldSelStart, OldSelLength: Integer;
- begin
- { Only proceed if the memo has a parent, and so is on-screen }
- if not Assigned(Parent) then
- Exit;
- MemoNumLines := ClientHeight div TextHeight('X');
- { Record where we were }
- OldSelStart := SelStart;
- OldSelLength := SelLength;
- if Perform(EM_GETLINECOUNT, 0, 0) > MemoNumLines then
- ScrollBars := ssVertical
- else
- ScrollBars := ssNone;
- { Go back to old position after memo control (possibly) recreated }
- SelStart := OldSelStart;
- SelLength := OldSelLength;
- end;
-
- end.
-